package com.yaowk.email.controller;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.kit.JMap;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.activerecord.tx.TxConfig;
import com.yaowk.authc.model.User;
import com.yaowk.common.kit.Constant;
import com.yaowk.common.kit.DateKit;
import com.yaowk.common.kit.ResultKit;
import com.yaowk.common.kit.YunbaKit;
import com.yaowk.common.validator.RequiredIdValidator;
import com.yaowk.email.model.Email;
import com.yaowk.email.model.EmailConsignee;
import com.yaowk.email.model.EmailFile;
import com.yaowk.email.model.EmailUser;
import com.yaowk.email.model.page.FeedbackPage;
import com.yaowk.email.model.page.SearchPage;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 邮件
 *
 * @authc yaowk
 * 2017/5/10
 */
@TxConfig(Constant.EMAIL_MODULE)
public class EmailController extends Controller {

    /**
     * 查阅反馈
     *
     * @title 查阅反馈
     */
    @RequiresPermissions("filePush:read")
    public void feedback() {
        FeedbackPage feedbackPage = getBean(FeedbackPage.class, "", true);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        Page result = EmailConsignee.dao.findFeedback(user.getId(), feedbackPage);
        renderJson(ResultKit.success(result));
    }

    /**
     * 查看邮件信息
     *
     * @param id|邮件id|Integer|必填
     * @title 查看邮件信息
     */
    @Before({ RequiredIdValidator.class, Tx.class })
    @RequiresPermissions("filePush:read")
    public void info() {

        // 查询邮件信息
        Integer id = getParaToInt("id");
        EmailUser emailUser = EmailUser.dao.findById(id);
        EmailConsignee emailConsignee = EmailConsignee.dao.findByEmailIdAndUserId(emailUser.getEmailId(), emailUser.getUserId()).get(0);

        // 设为已读，并记录查阅反馈
        Date date = new Date();
        emailUser.setTag(2).setReadTime(date).update();
        emailConsignee.setTag(2).setReadTime(date).update();

        JMap result = findEmailInfo(emailUser.getEmailId());
        renderJson(ResultKit.success(result));
    }

    /**
     * 搜索
     *
     * @param keyword|关键字|String|否
     * @param keywordType|关键字类型1-全部2-对象3-主题|Integer|是
     * @param type|状态0-已删除1-存草稿2-已发送3-收件箱4-全部|Integer|是
     * @title 搜索
     */
    @RequiresPermissions("filePush:read")
    public void search() {
        Integer keywordType = getParaToInt("keywordType");
        SearchPage searchPage = getBean(SearchPage.class, "", true);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        searchPage.setUserId(user.getId());

        // 处理关键字
        String keyword = getPara("keyword");
        if (StrKit.isBlank(keyword)) {
            keyword = "%%";
        }
        else {
            keyword = "%" + keyword + "%";
        }
        switch (keywordType) {
            case 1:
                searchPage.setConsigneeKeyword(keyword);
                searchPage.setTitleKeyword(keyword);
                break;
            case 2:
                searchPage.setConsigneeKeyword(keyword);
                break;
            case 3:
                searchPage.setTitleKeyword(keyword);
                break;
        }

        // 分页搜索
        Page<Email> page = Email.dao.search(searchPage);

        renderJson(ResultKit.success(page));
    }

    /**
     * 标记为
     *
     * @param id|邮件id|Integer[]|是
     * @param tag|标记为1-未读2-已读|Integer|是
     * @title 标记为
     */
    @RequiresPermissions("filePush:update")
    @Before(Tx.class)
    public void tag() {
        Object[] ids = getParaValuesToInt("id");
        Integer tag = getParaToInt("tag");
        if (StrKit.notNull(ids) && StrKit.notNull(tag)) {
            List<EmailUser> emailUserList = new ArrayList<>();
            for (Object id : ids) {
                emailUserList.add(EmailUser.dao.findById((Integer) id).setTag(tag));
            }
            Db.batchUpdate(emailUserList, emailUserList.size());
            renderJson(ResultKit.success(this));
        }
        else {
            renderJson(ResultKit.fail(this));
        }
    }


    /**
     * 保存草稿箱
     *
     * @param id|邮件id|Integer|否
     * @param title|主题|String|否
     * @param content|内容|String|否
     * @param sendTo|发送人|Integer[]|否
     * @param copyTo|抄送|Integer[]|否
     * @param file|附件|Integer[]|否
     * @param warningTime|预警时间|Long|否
     * @title 保存草稿箱
     */
    @Before(Tx.class)
    @RequiresPermissions("filePush:update")
    public void save() {
        saveEmail(0);
        renderJson(ResultKit.success(this));
    }

    /**
     * 发送邮件
     *
     * @param id|邮件id|Integer|否
     * @param title|主题|String|否
     * @param content|内容|String|否
     * @param sendTo|发送人|Integer[]|否
     * @param copyTo|抄送|Integer[]|否
     * @param file|附件|Integer[]|否
     * @param warningTime|预警时间|Long|否
     * @title 发送邮件
     */
    @Before(Tx.class)
    @RequiresPermissions("filePush:update")
    public void send() {

        // 保存发送邮件
        Integer emailId = saveEmail(1);

        // 推送邮件通知
        Integer[] sendTos = getParaValuesToInt("sendTo");
        Integer[] copyTos = getParaValuesToInt("copyTo");
        List<String> aliases = new ArrayList<>();
        for (Integer id : sendTos) {
            User user = User.dao.findById(id);
            aliases.add(user.getUsername());
        }
        for (Integer id : copyTos) {
            User user = User.dao.findById(id);
            aliases.add(user.getUsername());
        }
        YunbaKit.publishAliases(getPara("title"), aliases);
        renderJson(ResultKit.success(this));
    }

    /**
     * 删除
     *
     * @param id|邮件id|Integer[]|必填
     * @title 删除
     */
    @Before({ RequiredIdValidator.class, Tx.class })
    @RequiresPermissions("filePush:update")
    public void remove() {
        Integer[] ids = getParaValuesToInt("id");
        for (Integer id : ids) {
            EmailUser.dao.findById(id).setType(0).update();
        }
        renderJson(ResultKit.success(this));
    }

    /**
     * 彻底删除
     *
     * @param id|邮件id|Integer|必填
     * @title 彻底删除
     */
    @Before({ RequiredIdValidator.class, Tx.class })
    @RequiresPermissions("filePush:update")
    public void delete() {
        Integer[] ids = getParaValuesToInt("id");
        for (Integer id : ids) {
            EmailUser.dao.deleteById(id);
        }
        renderJson(ResultKit.success(this));
    }


    /**
     * 接口文档
     *
     * @title 接口文档
     */
    public void api() {
        render("../../../../email/src/test/email.html");
    }

    /**
     * 保存邮件
     */
    private Integer saveEmail(Integer lock) {

        User user = (User) SecurityUtils.getSubject().getPrincipal();
        // 保存邮件内容
        Integer emailId = getParaToInt("id");
        Email email;
        if (StrKit.notNull(emailId)) {
            email = Email.dao.findById(emailId);
        }
        else {
            email = new Email();

        }

        // 邮件已经发送不可更改
        if (StrKit.notNull(email.getLock()) && email.getLock() == 1) {
            throw new RuntimeException("email status has been send");
        }

        email.setTitle(getPara("title"))
                .setContent(getPara("content"))
                .setWarningTime(DateKit.toDate(getParaToLong("warningTime")))
                .setParent(getParaToInt("parentId"))
                .setLock(lock)
                .setTime(new Date());

        // 判断更新或者保存
        if (StrKit.notNull(email.getId())) {
            email.update();
        }
        else {
            email.save();
            new EmailUser()
                    .setEmailId(email.getId())
                    .setUserId(user.getId())
                    .save();

        }

        emailId = email.getId();
        // 保存发送人
        List<EmailConsignee> emailConsigneeList = new ArrayList<>();
        Object[] sendTos = getParaValuesToInt("sendTo");
        if (StrKit.notNull(sendTos)) {
            for (Object id : sendTos) {
                EmailConsignee emailConsignee = new EmailConsignee();
                emailConsignee.setEmailId(emailId)
                        .setUserId((Integer) id)
                        .setType(1);
                emailConsigneeList.add(emailConsignee);
            }
        }
        // 保存抄送人
        Object[] copyTos = getParaValuesToInt("copyTo");
        if (StrKit.notNull(copyTos)) {
            for (Object id : copyTos) {
                EmailConsignee emailConsignee = new EmailConsignee();
                emailConsignee.setEmailId(emailId)
                        .setUserId((Integer) id)
                        .setType(2);
                emailConsigneeList.add(emailConsignee);
            }
        }
        EmailConsignee.dao.deleteByEmailId(emailId);
        Db.batchSave(emailConsigneeList, emailConsigneeList.size());

        // 保存附件
        List<EmailFile> emailFileList = new ArrayList<>();
        Object[] files = getParaValuesToInt("file");
        if (StrKit.notNull(files)) {
            for (Object id : files) {
                EmailFile emailFile = new EmailFile();
                emailFile.setEmailId(emailId).setFileId((Integer) id);
                emailFileList.add(emailFile);
            }
        }
        EmailFile.dao.deleteByEmailId(emailId);
        Db.batchSave(emailFileList, emailFileList.size());

        // 发送
        if (lock == 1) {
            EmailUser emailUser = EmailUser.dao.findByEmailIdAndUserId(emailId, user.getId()).get(0);
            emailUser.setType(2).update(); // 设为已发送

            List<EmailUser> emailUserList = new ArrayList<>();
            for (EmailConsignee emailConsignee : emailConsigneeList) {
                emailUserList.add(
                        new EmailUser()
                                .setType(3)
                                .setEmailId(emailId)
                                .setUserId(emailConsignee.getUserId())
                );
            }
            Db.batchSave(emailUserList, emailUserList.size()); // 批量保存收件箱
        }

        return emailId;
    }

    private JMap findEmailInfo(Integer emailId) {
        // 查询邮件内容
        Email email = Email.dao.findById(emailId);

        // 查询发送者与附件
        List<EmailConsignee> emailConsigneeList = EmailConsignee.dao.findByEmailIdAndUserId(email.getId(), null);
        List<EmailFile> emailFileList = EmailFile.dao.findByEmailId(email.getId());

        JMap result = JMap.create().set("email", email).set("consignee", emailConsigneeList).set("file", emailFileList);
        return result;
    }

}
